package com.itheima.d5_dynamic_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
    经纪公司
       可以签约明星
       里面就一个功能
          签约明星给明星产生代理对象
 */
public class PTMCN {
    /**
     * 签约明星 产生明星的代理对象
     * @param superStar  具体的明星
     * @return 明星的代理对象
     */
    public static Star getProxy(Star superStar){
        //借助 JDK的Proxy.newProxyInstance()方法，获取代理对象
        // 参数1：类加载器--目的加载jdk产生的代理类 -- 当前类.class.getClassLoader()
        // 参数2：被代理者会实现的接口
        // 参数3：代理对象要做什么事情--代理对象的日常
        return (Star) Proxy.newProxyInstance(
                PTMCN.class.getClassLoader(),//代理类 使用 当前PTMCN的类加载器加载
                new Class[]{Star.class},//表示 被代理者 会的能力  会啥能力就能加强啥能力
                new InvocationHandler() {//在这里来定义 代理对象干什么事情
                    /*
                    下面这个方法 执行时机
                        当使用代理形式的时候,调用了 需要加强的方法--当前 sing dance rap 方法
                        这个方法会自动执行,没调用一次,执行一次。
                    方法作用:
                       就是用于 对原始方法 进行增强的
                       比如外界
                         假设调用的是  star.sing("凉凉");
                         method --- sing这个方法
                         args --- ["凉凉"]
                     */

                    /**
                     * 方法参数的解释--这些参数 JDK底层自动传输
                     * @param proxy   生成的代理对象--一般不用到
                     * @param method  当前正在执行的方法(原始的方法)  咱们调用的 sing() dance() rap()方法
                     * @param args    当前被增强的方法的参数 用数组接收方法的参数
                     * @return   方法的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        //对method 被增强的方法
                        String methodName = method.getName();
                        //假如是 sing方法 我们在调用原始的sing方法之前  要增强---准备话筒 ,收钱500W
                        if("sing".equals(methodName)){
                            System.out.println("准备话筒,收钱500W");
                            //还得调用原始方法
//                            return method.invoke(明星对象,参数);
                            return method.invoke(superStar,args);
                        }

                        if("dance".equals(methodName)){
                            System.out.println("准备舞台,收钱800W");
                            //还得调用原始方法
                            return method.invoke(superStar,args);
                        }
                        //其他不做增强
                        return method.invoke(superStar,args);
                    }
                }
        );
    }
}
